package Modelo.Edicao;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.List;

import Util.ExcecaoInstanciaNaoEncontrada;

public class EdicaoDao {
	public EdicaoDao() {
		super();
	}
	public Edicao adicionarEdicao(Connection connection,Edicao edicao){
		/* Criar "queryString". 
		 * Interrogacoes serao os parametros passados ao objeto
		 * preparedStatement*/
		String queryString = "INSERT INTO Edicao"
				+ " ( codEvento, localEdicao, dataIniEdicao, dataFimEdicao, nroInscritosEdicao) "
				+ "VALUES (?, ?, ?, ? ,0)";
		//Objeto que ira enviar a querrystring ao banco de dados e 
		//criara as chaves primarias
		try (PreparedStatement preparedStatement = connection.prepareStatement(
				queryString, Statement.RETURN_GENERATED_KEYS)) {

			int i = 1;
			int insertedRows = 0;
			//Coloca os parametros na mesma ordem indicada na querrystring
			preparedStatement.setLong(i++, edicao.getCodEvento());
			preparedStatement.setString(i++, edicao.getLocalEdicao());
			Timestamp dataIniEdicao = new Timestamp(edicao.getDataIniEdicao().getTimeInMillis());
			preparedStatement.setTimestamp(i++, dataIniEdicao);
			Timestamp dataFimEdicao = new Timestamp(edicao.getDataFimEdicao().getTimeInMillis());
			preparedStatement.setTimestamp(i++, dataFimEdicao);
			insertedRows = preparedStatement.executeUpdate(); //Executa o comando SQL

			if (insertedRows == 0) {
				throw new SQLException("Can not add row to table 'EdicaoIntern'");
			}

			if (insertedRows > 1) {
				throw new SQLException("Duplicate row in table 'EdicaoIntern'");
			}

			/* Pega a chave primaria. */
			ResultSet resultSet = preparedStatement.getGeneratedKeys();

			if (!resultSet.next()) {
				throw new SQLException(
						"JDBC driver did not return generated key.");
			}
			Integer nroEdicao = new Integer(resultSet.getInt(1));

			return new Edicao(edicao.getCodEvento(), nroEdicao, 
					edicao.getLocalEdicao(), edicao.getDataIniEdicao(), 
					edicao.getDataFimEdicao(), edicao.getNroInscritosEdicao());
			
			
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}
	
	public Edicao buscarEdicao(Connection connection, Long codEvento, int nroEdicao)
			throws ExcecaoInstanciaNaoEncontrada{
		
		String queryString = "SELECT localEdicao, dataIniEdicao, dataFimEdicao, nroInscritosEdicao"
				+ " FROM Edicao WHERE codEvento = ? AND nroEdicao = ?";
		
		try (java.sql.PreparedStatement preparedStatement = connection.prepareStatement(queryString)) {

			int i = 1;
			preparedStatement.setLong(i++, codEvento);
			preparedStatement.setInt(i++, nroEdicao);
			//Pega os Resultados da busca
			ResultSet resultSet = preparedStatement.executeQuery();

			if(!resultSet.next()){
				throw new ExcecaoInstanciaNaoEncontrada(new Long[]{codEvento, Long.valueOf(nroEdicao)}, "Edicao");

			}
			
			i = 1;
			String localEdicao = resultSet.getString(i++);
			Calendar dataIniEdicao = new GregorianCalendar();
			dataIniEdicao.setTimeInMillis((resultSet.getTimestamp(i++)).getTime());
			Calendar dataFimEdicao = new GregorianCalendar();
			dataFimEdicao.setTimeInMillis((resultSet.getTimestamp(i++)).getTime());
			int nroInscritosEdicao = resultSet.getInt(i++);
			return new Edicao(codEvento, nroEdicao, localEdicao, dataIniEdicao, dataFimEdicao, nroInscritosEdicao);


		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}
	public void removerEdicao(Connection connection, long codEvento, int nroEdicao)
			throws ExcecaoInstanciaNaoEncontrada{
		String queryString = "DELETE FROM Edicao WHERE codEvento = ? AND nroEdicao = ?";

		try (java.sql.PreparedStatement preparedStatement = connection.prepareStatement(queryString)) {
			int i = 1;
			preparedStatement.setLong(i++, codEvento);
			preparedStatement.setInt(i++, nroEdicao);

			int removedRows = preparedStatement.executeUpdate();

			if(removedRows == 0){
				throw new ExcecaoInstanciaNaoEncontrada(new Long []{codEvento, Long.valueOf(nroEdicao)}, "Edicao");
			}

		} catch (SQLException e) {
			throw new RuntimeException(e);
		}

	}
	public void updateEdicao(Connection connection, Edicao edicao) 
			throws ExcecaoInstanciaNaoEncontrada {

		int updateRows = 0;

		String queryString = "UPDATE Edicao "
				+ "SET localEdicao = ?, dataIniEdicao = ?, dataFimEdicao = ?, nroInscritosEdicao = ?" +
				" WHERE codEvento = ? AND nroEdicao = ?";

		try (java.sql.PreparedStatement preparedStatement = connection.prepareStatement(queryString)){
			int i = 1;
			preparedStatement.setString(i++, edicao.getLocalEdicao());
			Timestamp dataIniEdicao = new Timestamp(edicao.getDataIniEdicao().getTimeInMillis());
			preparedStatement.setTimestamp(i++, dataIniEdicao);
			Timestamp dataFimEdicao = new Timestamp(edicao.getDataFimEdicao().getTimeInMillis());
			preparedStatement.setTimestamp(i++, dataFimEdicao);
			preparedStatement.setInt(i++, edicao.getNroInscritosEdicao());
			preparedStatement.setLong(i++, edicao.getCodEvento());
			preparedStatement.setInt(i++, edicao.getNroEdicao());
			updateRows = preparedStatement.executeUpdate();

			if(updateRows == 0){
				throw new ExcecaoInstanciaNaoEncontrada(new Long []{edicao.getCodEvento(), 
						Long.valueOf(edicao.getNroEdicao())}, "Edicao");
			}

			else if(updateRows > 1){
				throw new SQLException("Linha duplicada para o identificador = '" + "' "
						+ "na tabela 'Edicao'");
			}


		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}
	/*Listar edicoes por evento*/
	public List<Edicao> buscarEdicoesPorEvento(Connection connection, Long codEvento) {

		String queryString = "SELECT * FROM Edicao "
				+ "WHERE codEvento = ?";
		try (java.sql.PreparedStatement preparedStatement = connection.prepareStatement(queryString)) {
			int i = 1;
			preparedStatement.setLong(i++, codEvento);
			
			ResultSet resultSet = preparedStatement.executeQuery();
			List<Edicao> edicoes = new ArrayList<Edicao>();

			while(resultSet.next()){
				i = 1;
				codEvento = resultSet.getLong(i++);
				int nroEdicao = resultSet.getInt(i++);
				String localEdicao = resultSet.getString(i++);
				Calendar dataIniEdicao = new GregorianCalendar();
				dataIniEdicao.setTimeInMillis((resultSet.getTimestamp(i++)).getTime());
				Calendar dataFimEdicao = new GregorianCalendar();
				dataFimEdicao.setTimeInMillis((resultSet.getTimestamp(i++)).getTime());
				int nroInscritosEdicao = resultSet.getInt(i++);
				edicoes.add(new Edicao(codEvento, nroEdicao, localEdicao, dataIniEdicao, dataFimEdicao, nroInscritosEdicao));
			}
			return edicoes;

		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}
}
